package com.trade.okxserver.util;

import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.trade.okxserver.operator.AvgOperator;
import com.trade.okxserver.operator.StandardOperator;
import com.trade.okxserver.operator.VarianceOperator;
import lombok.SneakyThrows;

import java.math.BigDecimal;
import java.util.Map;

public class ExpressUtils {

    private static final ExpressRunner runner = new ExpressRunner();

    static {
        try {
            runner.addOperatorWithAlias("如果", "if", null);
            runner.addOperatorWithAlias("则", "then", null);
            runner.addOperatorWithAlias("否则", "else", null);
            runner.addFunction("avg", new AvgOperator());
            runner.addFunction("std", new StandardOperator());
            runner.addFunction("var", new VarianceOperator());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @SneakyThrows
    public static Object execute(String express, Map<String, Object> params) {
        DefaultContext<String, Object> context = new DefaultContext<>();
        context.putAll(params);
        return runner.execute(express, context, null, true, false, 6000);
    }

    @SneakyThrows
    public static Object execute(String express, DefaultContext<String, Object> context) {
        return runner.execute(express, context, null, true, false, 6000);
    }

    public static ExpressRunner getRunner(){
        return runner;
    }


    public static void main(String[] args) {
        //       - {"variable": "standard", "rule": "std(K1H,K1L,K2H,K2L)"}
        //      - {"variable": "a", "rule": "K1H + K1L + K2H + K2L + standard"}
        //      - {"variable": "buyPrice", "rule": "((5*a - 3*a)/2 - (K1H + K1L + K2H + K2L))/2"}

        DefaultContext<String, Object> objectObjectDefaultContext = new DefaultContext<>();
        objectObjectDefaultContext.put("a", 1);
        objectObjectDefaultContext.put("b", 2);
        objectObjectDefaultContext.put("c", 3);
        objectObjectDefaultContext.put("d", 4);
        Object standard = execute("std(a,b,c,d)", objectObjectDefaultContext);
        objectObjectDefaultContext.put("standard", new BigDecimal(standard.toString()));
        Object x = execute("standard + a + b +c +d", objectObjectDefaultContext);
        objectObjectDefaultContext.put("x", new BigDecimal(x.toString()));
        Object execute = execute("((5*x - 3*x)/2 - (a + b + c + d))/2", objectObjectDefaultContext);
        System.out.println(execute);
    }
}
